home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 2 / Amiga Tools 2.iso / tools / jade / src / amiga_misc.c < prev    next >
C/C++ Source or Header  |  1995-03-09  |  17KB  |  673 lines

  1. /* amiga_misc.c -- Miscellaneous functions for AmigaDOS
  2.    Copyright (C) 1993, 1994 John Harper <jsh@ukc.ac.uk>
  3.  
  4.    This file is part of Jade.
  5.  
  6.    Jade is free software; you can redistribute it and/or modify it
  7.    under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2, or (at your option)
  9.    any later version.
  10.  
  11.    Jade is distributed in the hope that it will be useful, but
  12.    WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with Jade; see the file COPYING.    If not, write to
  18.    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "jade.h"
  21. #include "jade_protos.h"
  22.  
  23. #include <clib/dos_protos.h>
  24. #define INTUI_V36_NAMES_ONLY
  25. #include <clib/intuition_protos.h>
  26. #include <clib/asl_protos.h>
  27. #include <exec/initializers.h>
  28. #include <string.h>
  29. #include <stdlib.h>
  30.  
  31. _PR void freq_kill(void);
  32. _PR void beep(VW *);
  33. _PR bool same_files(u_char *, u_char *);
  34. _PR u_char *file_part(u_char *);
  35. _PR void NewList(struct List *);
  36. _PR VALUE lookup_errno(void);
  37. _PR void doconmsg(u_char *);
  38. _PR VALUE read_file(u_char *);
  39.  
  40. _PR bool file_exists(u_char *);
  41. _PR long file_mod_time(u_char *);
  42. _PR long sys_time(void);
  43. _PR int add_file_part(u_char *, u_char *, int);
  44. _PR VALUE sys_expand_file_name(VALUE);
  45. _PR VALUE sys_fully_qualify_file_name(VALUE);
  46.  
  47. _PR void sys_misc_init(void);
  48.  
  49. /*
  50.  * File req stuff.
  51.  * I don't like the ASL requester but I couldn't be bothered to make the DICE
  52.  * libraries for reqtools.library. Use the RTpatch prog to get nice (fast)
  53.  * requesters.
  54.  */
  55. void *AslBase;
  56. static struct FileRequester *file_req;
  57.  
  58. void
  59. freq_kill(void)
  60. {
  61.     if(file_req)
  62.     {
  63.     FreeAslRequest(file_req);
  64.     file_req = NULL;
  65.     }
  66.     if(AslBase)
  67.     {
  68.     CloseLibrary(AslBase);
  69.     AslBase = NULL;
  70.     }
  71. }
  72.  
  73. _PR VALUE cmd_file_req(VALUE title, VALUE filename, VALUE writep);
  74. DEFUN("file-req", cmd_file_req, subr_file_req, (VALUE title, VALUE filename, VALUE writep), V_Subr3, DOC_file_req) /*
  75. ::doc:file_req::
  76. file-req TITLE [FILE-NAME] [FOR-WRITING-P]
  77. <AMIGA ONLY>
  78.  
  79. Displays a file requester (standard one from asl.library) asking for the name
  80. of a file. FOR-WRITING-P should be non-nil if the file being requested for
  81. will be written to. TITLE is the name of the requester. FILE-NAME is
  82. the starting value for the filename.
  83.  
  84. If a filename is selected its name is returned (a string), else this
  85. function returns nil.
  86. ::end:: */
  87. {
  88.     VALUE result = sym_nil;
  89.     DECLARE1(title, STRINGP);
  90.     if(!STRINGP(filename))
  91.     filename = null_string;
  92.     if(AslBase || (AslBase = OpenLibrary("asl.library", 36)))
  93.     {
  94.     if(file_req
  95.        || (file_req = AllocAslRequestTags(ASL_FileRequest, TAG_DONE)))
  96.     {
  97.         u_short flags = 0;
  98.         u_char *dircopy;
  99.         if(!NILP(writep))
  100.         flags |= FILF_SAVE;
  101.         if(dircopy = str_dup(VSTR(filename)))
  102.         {
  103.         u_char *actualfile = FilePart(VSTR(filename));
  104.         dircopy[actualfile - VSTR(filename)] = 0;
  105.         if(AslRequestTags(file_req,
  106.             ASL_Hail, VSTR(title),
  107.             ASL_Window, curr_vw->vw_Window,
  108.             ASL_File, actualfile,
  109.             ASL_Dir, dircopy,
  110.             ASL_FuncFlags, flags,
  111.             TAG_END))
  112.         {
  113.             long sellen = strlen(file_req->rf_File) + strlen(file_req->rf_Dir) + 2;
  114.             if(result = make_string(sellen))
  115.             {
  116.             strcpy(VSTR(result), file_req->rf_Dir);
  117.             AddPart(VSTR(result), file_req->rf_File, sellen);
  118.             /* Ensure that the length field contains the *correct*
  119.                value.  */
  120.             DSTRING_HDR(result)->ds_Length = strlen(VSTR(result));
  121.             }
  122.             else
  123.             mem_error();
  124.         }
  125.         str_free(dircopy);
  126.         }
  127.         else
  128.         mem_error();
  129.     }
  130.     else
  131.         cmd_signal(sym_error, LIST_1(MKSTR("Can't allocate file requester")));
  132.     }
  133.     else
  134.     cmd_signal(sym_error, LIST_1(MKSTR("Need `asl.library'")));
  135.     return(result);
  136. }
  137.  
  138. void
  139. beep(VW *vw)
  140. {
  141.     DisplayBeep(vw->vw_Window->WScreen);
  142. }
  143.  
  144. bool
  145. same_files(u_char *file1, u_char *file2)
  146. {
  147.     bool rc = FALSE;
  148.     BPTR lck1;
  149.     if(lck1 = Lock(file1, SHARED_LOCK))
  150.     {
  151.     BPTR lck2;
  152.     if(lck2 = Lock(file2, SHARED_LOCK))
  153.     {
  154.         if(SameLock(lck1, lck2) == LOCK_SAME)
  155.         rc = TRUE;
  156.         UnLock(lck2);
  157.     }
  158.     UnLock(lck1);
  159.     }
  160.     else
  161.     rc = !stricmp(file1, file2);
  162.     return(rc);
  163. }
  164.  
  165. u_char *
  166. file_part(u_char *file)
  167. {
  168.     return(FilePart(file));
  169. }
  170.  
  171. #ifdef _DCC
  172. void
  173. NewList(struct List *list)
  174. {
  175.     list->lh_Head = (struct Node *)&list->lh_Tail;
  176.     list->lh_Tail = NULL;
  177.     list->lh_TailPred = (struct Node *)&list->lh_Head;
  178. }
  179. #endif
  180.  
  181. VALUE
  182. lookup_errno(void)
  183. {
  184.     u_char buf[256];
  185.     if(!Fault(IoErr(), "", buf, 256))
  186.     sprintf(buf, "%d", IoErr());
  187.     return(string_dup(buf));
  188. }
  189.  
  190. void
  191. doconmsg(u_char *msg)
  192. {
  193.     /*
  194.      * CLI/WB & 1.3/2.0 compatible
  195.      */
  196.     if(ami_from_wb)
  197.     {
  198.     BPTR fh = Open("CON:///80/Jade output/WAIT/CLOSE", MODE_NEWFILE);
  199.     if(fh)
  200.         Write(fh, msg, strlen(msg));
  201.     Close(fh);
  202.     }
  203.     else
  204.     Write(Output(), msg, strlen(msg));
  205. }
  206.  
  207. VALUE
  208. read_file(u_char *fileName)
  209. {
  210.     BPTR fh = Open(fileName, MODE_OLDFILE);
  211.     if(fh)
  212.     {
  213.     long length;
  214.     VALUE mem;
  215.     Seek(fh, 0, OFFSET_END);
  216.     length = Seek(fh, 0, OFFSET_BEGINNING);
  217.     if(mem = make_string(length + 1))
  218.     {
  219.         Read(fh, VSTR(mem), length);
  220.         VSTR(mem)[length] = 0;
  221.         Close(fh);
  222.         return(mem);
  223.     }
  224.     else
  225.         mem_error();
  226.     Close(fh);
  227.     }
  228.     return(cmd_signal(sym_file_error, list_2(lookup_errno(), string_dup(fileName))));
  229. }
  230.  
  231. int
  232. add_file_part(u_char *buf, u_char *part, int len)
  233. {
  234.     return(AddPart(buf, part, len));
  235. }
  236.  
  237. VALUE
  238. sys_expand_file_name(VALUE name)
  239. {
  240.     return(name);
  241. }
  242.  
  243. VALUE
  244. sys_fully_qualify_file_name(VALUE name)
  245. {
  246.     u_char buf[512];
  247.     BPTR lock = Lock(VSTR(name), ACCESS_READ);
  248.     if(lock)
  249.     {
  250.     /* easy, just expand from the lock. */
  251.     if(NameFromLock(lock, buf, 512))
  252.         name = string_dup(buf);
  253.     else
  254.         name = NULL;
  255.     }
  256.     else
  257.     {
  258.     /* trickier, the file doesn't exist; find its parent and work from
  259.        there. */
  260.     long len = PathPart(VSTR(name)) - VSTR(name);
  261.     memcpy(buf, VSTR(name), len);
  262.     buf[len] = 0;
  263.     lock = Lock(buf, ACCESS_READ);
  264.     if(lock && NameFromLock(lock, buf, 512))
  265.     {
  266.         if(add_file_part(buf, VSTR(name) + len, 512))
  267.         name = string_dup(buf);
  268.         else
  269.         name = NULL;
  270.     }
  271.     }
  272.     if(lock != NULL)
  273.     UnLock(lock);
  274.     return(name);
  275. }
  276.  
  277. long
  278. getfibfield(u_char *file, int field)
  279. {
  280.     long rc = 0;
  281.     BPTR lock;
  282.     if(lock = Lock(file, SHARED_LOCK))
  283.     {
  284.     struct FileInfoBlock *fib;
  285.     if(fib = mymalloc(sizeof(struct FileInfoBlock)))
  286.     {
  287.         if(Examine(lock, fib))
  288.         rc = *(LONG *)((char *)fib + field);
  289.         myfree(fib);
  290.     }
  291.     UnLock(lock);
  292.     }
  293.     return(rc);
  294. }
  295.  
  296. _PR VALUE cmd_flush_output(void);
  297. DEFUN("flush-output", cmd_flush_output, subr_flush_output, (void), V_Subr0, DOC_flush_output)
  298. {
  299.     return(sym_t);
  300. }
  301.  
  302. _PR VALUE cmd_delete_file(VALUE file);
  303. DEFUN_INT("delete-file", cmd_delete_file, subr_delete_file, (VALUE file), V_Subr1, DOC_delete_file, "fDelete file:")
  304. {
  305.     DECLARE1(file, STRINGP);
  306.     if(DeleteFile(VSTR(file)))
  307.     return(sym_t);
  308.     return(cmd_signal(sym_file_error, list_2(lookup_errno(), file)));
  309. }
  310.  
  311. _PR VALUE cmd_rename_file(VALUE src, VALUE dst);
  312. DEFUN_INT("rename-file", cmd_rename_file, subr_rename_file, (VALUE src, VALUE dst), V_Subr2, DOC_rename_file, "fRename file:\nFRename file `%s' as:")
  313. {
  314.     DECLARE1(src, STRINGP);
  315.     DECLARE2(dst, STRINGP);
  316.     if(Rename(VSTR(src), VSTR(dst)))
  317.     return(sym_t);
  318.     return(cmd_signal(sym_file_error, list_3(lookup_errno(), src, dst)));
  319. }
  320.  
  321. _PR VALUE cmd_copy_file(VALUE src, VALUE dst);
  322. DEFUN_INT("copy-file", cmd_copy_file, subr_copy_file, (VALUE src, VALUE dst), V_Subr2, DOC_copy_file, "fCopy file:\nFCopy file `%s' to:")
  323. {
  324.     VALUE res = sym_t;
  325.     BPTR srcf;
  326.     DECLARE1(src, STRINGP);
  327.     DECLARE2(dst, STRINGP);
  328.     srcf = Open(VSTR(src), MODE_OLDFILE);
  329.     if(srcf != NULL)
  330.     {
  331.     int dstf = Open(VSTR(dst), MODE_NEWFILE);
  332.     if(dstf != NULL)
  333.     {
  334.         int rd;
  335.         int prot = getfibfield(VSTR(src), (int)OFFSET(FileInfoBlock, fib_Protection));
  336.         if(prot != 0)
  337.         SetProtection(VSTR(dst), prot &~ FIBF_ARCHIVE);
  338.         do {
  339.         u_char buf[BUFSIZ];
  340.         int wr;
  341.         rd = Read(srcf, buf, BUFSIZ);
  342.         if(rd < 0)
  343.         {
  344.             res = signal_file_error(src);
  345.             break;
  346.         }
  347.         wr = Write(dstf, buf, rd);
  348.         if(wr != rd)
  349.         {
  350.             res = signal_file_error(dst);
  351.             break;
  352.         }
  353.         } while(rd != 0);
  354.         Close(dstf);
  355.     }
  356.     else
  357.         res = signal_file_error(dst);
  358.     Close(srcf);
  359.     }
  360.     else
  361.     res = signal_file_error(src);
  362.     return(res);
  363. }
  364.  
  365. _PR VALUE cmd_file_readable_p(VALUE file);
  366. DEFUN("file-readable-p", cmd_file_readable_p, subr_file_readable_p, (VALUE file), V_Subr1, DOC_file_readable_p)
  367. {
  368.     int prot;
  369.     DECLARE1(file, STRINGP);
  370.     prot= getfibfield(VSTR(file), (int)OFFSET(FileInfoBlock, fib_Protection));
  371.     if(~prot & FIBF_READ)
  372.     return(sym_t);
  373.     return(sym_nil);
  374. }
  375.  
  376. _PR VALUE cmd_file_writable_p(VALUE file);
  377. DEFUN("file-writable-p", cmd_file_writable_p, subr_file_writable_p, (VALUE file), V_Subr1, DOC_file_writeable_p)
  378. {
  379.     int prot;
  380.     DECLARE1(file, STRINGP);
  381.     prot = getfibfield(VSTR(file), (int)OFFSET(FileInfoBlock, fib_Protection));
  382.     if(~prot & FIBF_WRITE)
  383.     return(sym_t);
  384.     return(sym_nil);
  385. }
  386.  
  387. _PR VALUE cmd_file_exists_p(VALUE file);
  388. DEFUN("file-exists-p", cmd_file_exists_p, subr_file_exists_p, (VALUE file), V_Subr1, DOC_file_exists_p)
  389. {
  390.     BPTR lock;
  391.     DECLARE1(file, STRINGP);
  392.     if(lock = Lock(VSTR(file), SHARED_LOCK))
  393.     {
  394.     UnLock(lock);
  395.     return(sym_t);
  396.     }
  397.     return(sym_nil);
  398. }
  399.  
  400. bool
  401. file_exists(u_char *fileName)
  402. {
  403.     BPTR lock;
  404.     if(lock = Lock(fileName, SHARED_LOCK))
  405.     {
  406.     int type;
  407.     UnLock(lock);
  408.     type = getfibfield(fileName, (int)OFFSET(FileInfoBlock, fib_DirEntryType));
  409.     /* Only allow _files_ */
  410.     if(type < 0)
  411.         return(TRUE);
  412.     }
  413.     return(FALSE);
  414. }
  415.  
  416. _PR VALUE cmd_file_regular_p(VALUE file);
  417. DEFUN("file-regular-p", cmd_file_regular_p, subr_file_regular_p, (VALUE file), V_Subr1, DOC_file_regular_p)
  418. {
  419.     int type;
  420.     DECLARE1(file, STRINGP);
  421.     if(type = getfibfield(VSTR(file), (int)OFFSET(FileInfoBlock, fib_DirEntryType)))
  422.     {
  423.     if(type < 0)
  424.         return(sym_t);
  425.     }
  426.     return(sym_nil);
  427. }
  428.  
  429. _PR VALUE cmd_file_directory_p(VALUE file);
  430. DEFUN("file-directory-p", cmd_file_directory_p, subr_file_directory_p, (VALUE file), V_Subr1, DOC_file_directory_p)
  431. {
  432.     int type;
  433.     DECLARE1(file, STRINGP);
  434.     if(type = getfibfield(VSTR(file), (int)OFFSET(FileInfoBlock, fib_DirEntryType)))
  435.     {
  436.     /* There may be a problem here, ST_SOFTLINK>0 so, these will make
  437.        this function return t.  */
  438.     if(type > 0)
  439.         return(sym_t);
  440.     }
  441.     return(sym_nil);
  442. }
  443.  
  444. _PR VALUE cmd_file_symlink_p(VALUE file);
  445. DEFUN("file-symlink-p", cmd_file_symlink_p, subr_file_symlink_p, (VALUE file), V_Subr1, DOC_file_symlink_p)
  446. {
  447.     int type;
  448.     DECLARE1(file, STRINGP);
  449.     if(type = getfibfield(VSTR(file), (int)OFFSET(FileInfoBlock, fib_DirEntryType)))
  450.     {
  451.     if(type == ST_SOFTLINK)
  452.         return(sym_t);
  453.     }
  454.     return(sym_nil);
  455. }
  456.  
  457. _PR VALUE cmd_file_owner_p(VALUE file);
  458. DEFUN("file-owner-p", cmd_file_owner_p, subr_file_owner_p, (VALUE file), V_Subr1, DOC_file_owner_p)
  459. {
  460.     return(sym_t);
  461. }
  462.  
  463. _PR VALUE cmd_file_nlinks(VALUE file);
  464. DEFUN("file-nlinks", cmd_file_nlinks, subr_file_nlinks, (VALUE file), V_Subr1, DOC_file_nlinks)
  465. {
  466.     /* I don't know how to do this in AmigaDOS -- is it possible? */
  467.     return(make_number(1));
  468. }
  469.  
  470. _PR VALUE cmd_file_modes(VALUE file);
  471. DEFUN("file-modes", cmd_file_modes, subr_file_modes, (VALUE file), V_Subr1, DOC_file_modes)
  472. {
  473.     DECLARE1(file, STRINGP);
  474.     int bits = getfibfield(VSTR(file), (int)OFFSET(FileInfoBlock, fib_Protection));
  475.     if(bits != 0)
  476.     return(make_number(bits));
  477.     return(sym_nil);
  478. }
  479.  
  480. _PR VALUE cmd_set_file_modes(VALUE file, VALUE modes);
  481. DEFUN("set-file-modes", cmd_set_file_modes, subr_set_file_modes, (VALUE file, VALUE modes), V_Subr2, DOC_set_file_modes)
  482. {
  483.     DECLARE1(file, STRINGP);
  484.     DECLARE2(modes, NUMBERP);
  485.     if(SetProtection(VSTR(file), VNUM(modes) & ~FIBF_ARCHIVE))
  486.     return(sym_t);
  487.     return(signal_file_error(file));
  488. }
  489.  
  490. static long
  491. dstotime(struct DateStamp *ds)
  492. {
  493.     return((ds->ds_Days * 86400) + (ds->ds_Minute * 60) + (ds->ds_Tick / TICKS_PER_SECOND));
  494. }
  495.  
  496. long
  497. file_mod_time(u_char *fileName)
  498. {
  499.     long time = 0;
  500.     BPTR lock;
  501.     if(lock = Lock(fileName, SHARED_LOCK))
  502.     {
  503.     struct FileInfoBlock *fib;
  504.     if(fib = mymalloc(sizeof(struct FileInfoBlock)))
  505.     {
  506.         if(Examine(lock, fib))
  507.         time = dstotime(&fib->fib_Date);
  508.         myfree(fib);
  509.     }
  510.     UnLock(lock);
  511.     }
  512.     return(time);
  513. }
  514.  
  515. long
  516. sys_time(void)
  517. {
  518.     struct DateStamp ds;
  519.     DateStamp(&ds);
  520.     return(dstotime(&ds));
  521. }
  522.  
  523. _PR VALUE cmd_file_modtime(VALUE file);
  524. DEFUN("file-modtime", cmd_file_modtime, subr_file_modtime, (VALUE file), V_Subr1, DOC_file_modtime)
  525. {
  526.     DECLARE1(file, STRINGP);
  527.     return(make_number(file_mod_time(VSTR(file))));
  528. }
  529.  
  530. _PR VALUE cmd_directory_files(VALUE dir);
  531. DEFUN("directory-files", cmd_directory_files, subr_directory_files, (VALUE dir), V_Subr1, DOC_directory_files)
  532. {
  533.     BPTR dirlock;
  534.     DECLARE1(dir, STRINGP);
  535.     if(dirlock = Lock(VSTR(dir), SHARED_LOCK))
  536.     {
  537.     VALUE list = sym_nil;
  538.     struct FileInfoBlock *fib;
  539.     if(fib = mymalloc(sizeof(struct FileInfoBlock)))
  540.     {
  541.         if(Examine(dirlock, fib))
  542.         {
  543.         while(ExNext(dirlock, fib))
  544.         {
  545.             VALUE name;
  546.             if(!((name = string_dup(fib->fib_FileName)) && (list = cmd_cons(name, list))))
  547.             {
  548.             myfree(fib);
  549.             UnLock(dirlock);
  550.             return(mem_error());
  551.             }
  552.         }
  553.         }
  554.         myfree(fib);
  555.     }
  556.     UnLock(dirlock);
  557.     return(list);
  558.     }
  559.     return(cmd_signal(sym_file_error, list_2(lookup_errno(), dir)));
  560. }
  561.  
  562. _PR VALUE cmd_user_login_name(void);
  563. DEFUN("user-login-name", cmd_user_login_name, subr_user_login_name, (void), V_Subr0, DOC_user_login_name)
  564. {
  565.     char *name;
  566.     /* Just look this up once, then use the saved copy.  */
  567.     static VALUE user_login_name;
  568.     if(user_login_name)
  569.     return(user_login_name);
  570.     name = getenv("USERNAME");
  571.     if(name)
  572.     user_login_name = string_dup(name);
  573.     else
  574.     user_login_name = MKSTR("<unknown username>");
  575.     mark_static(&user_login_name);
  576.     return(user_login_name);
  577. }
  578.  
  579. _PR VALUE cmd_user_full_name(void);
  580. DEFUN("user-full-name", cmd_user_full_name, subr_user_full_name, (void), V_Subr0, DOC_user_full_name)
  581. {
  582.     char *name;
  583.     static VALUE user_full_name;
  584.     if(user_full_name)
  585.     return(user_full_name);
  586.     name = getenv("REALNAME");
  587.     if(name)
  588.     user_full_name = string_dup(name);
  589.     else
  590.     user_full_name = MKSTR("<unknown full name>");
  591.     mark_static(&user_full_name);
  592.     return(user_full_name);
  593. }
  594.  
  595. _PR VALUE cmd_user_home_directory(void);
  596. DEFUN("user-home-directory", cmd_user_home_directory, subr_user_home_directory, (void), V_Subr0, DOC_user_home_directory)
  597. {
  598.     char *home;
  599.     static VALUE user_home_directory;
  600.     if(user_home_directory)
  601.     return(user_home_directory);
  602.     home = getenv("HOME");
  603.     if(home)
  604.     user_home_directory = string_dup(home);
  605.     else
  606.     user_home_directory = MKSTR("SYS:");
  607.     mark_static(&user_home_directory);
  608.     return(user_home_directory);
  609. }
  610.  
  611. _PR VALUE cmd_system_name(void);
  612. DEFUN("system-name", cmd_system_name, subr_system_name, (void), V_Subr0,  DOC_system_name)
  613. {
  614.     char *name;
  615.     static VALUE system_name;
  616.     if(system_name)
  617.     return(system_name);
  618.     name = getenv("HOSTNAME");
  619.     if(name)
  620.     system_name = string_dup(name);
  621.     else
  622.     system_name = MKSTR("<unknown system name>");
  623.     mark_static(&system_name);
  624.     return(system_name);
  625. }
  626.  
  627. _PR VALUE cmd_setenv(VALUE name, VALUE val);
  628. DEFUN("setenv", cmd_setenv, subr_setenv, (VALUE name, VALUE val), V_Subr2, DOC_setenv)
  629. {
  630.     DECLARE1(name, STRINGP);
  631.     if(!STRINGP(val))
  632.     {
  633.     /* deleting the variable NAME */
  634.     return(DeleteVar(VSTR(name), GVF_GLOBAL_ONLY) ? sym_t : sym_nil);
  635.     }
  636.     else
  637.     {
  638.     /* setting NAME to VAL */
  639.     if(SetVar(VSTR(name), VSTR(val), STRING_LEN(val), GVF_GLOBAL_ONLY))
  640.         return(val);
  641.     else
  642.         return(cmd_signal(sym_file_error,
  643.                   list_2(MKSTR("Can't set env variable"), name)));
  644.     }
  645. }
  646.  
  647. void
  648. sys_misc_init(void)
  649. {
  650.     ADD_SUBR(subr_file_req);
  651.     ADD_SUBR(subr_flush_output);
  652.     ADD_SUBR(subr_delete_file);
  653.     ADD_SUBR(subr_rename_file);
  654.     ADD_SUBR(subr_copy_file);
  655.     ADD_SUBR(subr_file_readable_p);
  656.     ADD_SUBR(subr_file_writable_p);
  657.     ADD_SUBR(subr_file_exists_p);
  658.     ADD_SUBR(subr_file_regular_p);
  659.     ADD_SUBR(subr_file_directory_p);
  660.     ADD_SUBR(subr_file_symlink_p);
  661.     ADD_SUBR(subr_file_owner_p);
  662.     ADD_SUBR(subr_file_nlinks);
  663.     ADD_SUBR(subr_file_modes);
  664.     ADD_SUBR(subr_set_file_modes);
  665.     ADD_SUBR(subr_file_modtime);
  666.     ADD_SUBR(subr_directory_files);
  667.     ADD_SUBR(subr_user_login_name);
  668.     ADD_SUBR(subr_user_full_name);
  669.     ADD_SUBR(subr_user_home_directory);
  670.     ADD_SUBR(subr_system_name);
  671.     ADD_SUBR(subr_setenv);
  672. }
  673.